package com.ytf.test.eighth;

class Shared{
    // 复用次数
    private int refcount = 0;
    // 静态确定创建次数
    private static long counter = 0;
    // 新建对象固定id
    private final long id = counter++;
    public Shared() {
        this.refcount++;
        System.out.println("Creating "+this);
    }

    public void addRef(){
        this.refcount++;
    }
    protected void dispose(){
        if (--refcount == 0) {
            System.out.println("disposing "+this);
        }
    }

    @Override
    public String toString() {
        return "Shared{" +
                "refcount=" + refcount +
                ", id=" + id +
                '}';
    }
}

class Composing{
    private Shared shared;
    private static long counter = 0;
    private final long id = counter++;

    public Composing(Shared shared) {
        this.shared = shared;
        this.shared.addRef();
        System.out.println("Creating "+this);
    }

    protected void dispose(){
        System.out.println("disposing "+this);
        shared.dispose();
    }

    @Override
    public String toString() {
        return "Composing{" +
                "shared=" + shared +
                ", id=" + id +
                '}';
    }
}
class Poetry extends Shared{
    private int refcount = 0;
    private static long counter = 0;
    private final long id = counter++;

    public Poetry() {
        super();
        this.refcount++;
        System.out.println("Create Poetry "+this);
    }

    @Override
    public void addRef() {
        this.refcount++;
    }

    @Override
    protected void dispose(){
        if (--refcount ==0 ){
            super.dispose();
            System.out.println("dispose "+this);
        }
    }

    @Override
    public String toString() {
        return "Poetry{" +
                "refcount=" + refcount +
                ", id=" + id +
                '}';
    }
}
/**
 * @author: YTF
 * @date: 2025/1/24 18:19
 * @version: 1.0
 * @description:
 */
public class ReferenceCounting {
    public static void main(String[] args) {
        // Shared shared = new Shared();
        // System.out.println(shared.toString());
        // Composing[] composings = {new Composing(shared),new Composing(shared),new Composing(shared),new Composing(shared)};
        // for (Composing c :composings ) {
        //     c.dispose();
        // }
        // shared.dispose();
        /**
         * OutPut:
         * Creating Shared{refcount=1, id=0}
         * Shared{refcount=1, id=0}
         * Creating Composing{shared=Shared{refcount=2, id=0}, id=0}
         * Creating Composing{shared=Shared{refcount=3, id=0}, id=1}
         * Creating Composing{shared=Shared{refcount=4, id=0}, id=2}
         * Creating Composing{shared=Shared{refcount=5, id=0}, id=3}
         * disposing Composing{shared=Shared{refcount=5, id=0}, id=0}
         * disposing Composing{shared=Shared{refcount=4, id=0}, id=1}
         * disposing Composing{shared=Shared{refcount=3, id=0}, id=2}
         * disposing Composing{shared=Shared{refcount=2, id=0}, id=3}
         * disposing Shared{refcount=0, id=0}
         */
        extend();
    }

    /**
     * 延伸思考：
     * 如何有继承类应该如何计数 正常计数
     * 继承和组合计数方式有那些区别 (没有区别： 不管是组合还是继承都是父类新建和复用时才会有变化，和组合继承没关系。)
     * 需要注意的是：this关键字总是引用当前对象的实例，而当前对象是子类实例所以输出的对象地址也是子类的 下面有相关实例进行测试
     */
    public static void extend(){
        System.out.println();
        Poetry poetry = new Poetry();
        poetry.dispose();
        // this测试
        Child child = new Child();
    }
}
class Parent {
    public Parent() {
        System.out.println("Parent constructor called");
        System.out.println("Inside Parent constructor, this is: " + this);
    }
}

class Child extends Parent {
    public Child() {
        super(); // Calls the constructor of the Parent class
        System.out.println("Child constructor called");
        System.out.println("Inside Child constructor, this is: " + this);
    }
}


